package com.zx.system.block.service.impl;

import com.zx.core.constant.SystemConstants;
import com.zx.core.context.TenantContextHolder;
import com.zx.core.enums.StatusEnum;
import com.zx.core.page.PageInfo;
import com.zx.core.wrapper.ListWrapper;
import com.zx.core.wrapper.ObjectWrapper;
import com.zx.core.wrapper.PageWrapper;
import com.zx.core.wrapper.ResponseWrapper;
import com.zx.security.block.uitls.SecurityUtils;
import com.zx.system.block.dao.SysTenantMapper;
import com.zx.system.block.mapstruct.TenantMapStructMapper;
import com.zx.system.block.model.SysTenant;
import com.zx.system.block.param.TenantParam;
import com.zx.system.block.service.ISysTenantService;
import com.zx.system.block.utils.SystemNoUtils;
import com.zx.system.block.vo.SysTenantVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * <p>
 * description: 业务层租户服务实现 <br>
 * create: 2025-11-23
 * </p>
 *
 * @author zhou xun
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysTenantServiceImpl implements ISysTenantService {
    private final SysTenantMapper sysTenantMapper;

    /**
     * 分页查询租户列表VO
     *
     * @param tenantParam 租户查询参数
     * @return {@link PageWrapper<SysTenantVO>}
     * @author zhou xun
     * @since 2025-11-23
     */
    @Override
    public PageWrapper<SysTenantVO> getTenantVOListByPage(TenantParam tenantParam) {
        PageWrapper<SysTenantVO> result = new PageWrapper<>();
        try {
            // 处理分页参数
            PageInfo pageInfo = new PageInfo(tenantParam.getPageNum(), tenantParam.getPageSize());
            tenantParam.setPageNum(pageInfo.getPageNum());
            tenantParam.setPageSize(pageInfo.getPageSize());

            // 查询总数
            Long count = sysTenantMapper.selectTenantCount(
                    tenantParam.getName(),
                    tenantParam.getContactPerson(),
                    tenantParam.getContactPhone(),
                    tenantParam.getStatus(),
                    tenantParam.getCreateTimeStart(),
                    tenantParam.getCreateTimeEnd()
            );

            if (count > 0) {
                // 查询列表
                List<SysTenant> tenantList = sysTenantMapper.selectTenantListByPage(
                        tenantParam.getName(),
                        tenantParam.getContactPerson(),
                        tenantParam.getContactPhone(),
                        tenantParam.getStatus(),
                        tenantParam.getCreateTimeStart(),
                        tenantParam.getCreateTimeEnd(),
                        tenantParam.getPageNum(),
                        tenantParam.getPageSize()
                );

                // 转换为VO对象
                List<SysTenantVO> voList = tenantList.stream()
                        .map(sysTenant -> {
                            // 使用MapStruct进行基础属性转换和描述性字段设置
                            SysTenantVO sysTenantVSO = TenantMapStructMapper.INSTANCE.sysTenantToSysTenantVO(sysTenant);
                            return sysTenantVSO;
                        })
                        .collect(Collectors.toList());

                result.setData(voList);
                result.setTotal(count);
                result.setCurrentPageNum(tenantParam.getPageNum());
                result.setTotalPage(pageInfo);
            }
        } catch (Exception e) {
            log.error("分页查询租户列表时发生错误", e);
            result.fail("分页查询租户列表时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 新增租户
     *
     * @param tenantParam 租户参数
     * @return {@link ResponseWrapper}
     * @author zhou xun
     * @since 2025-11-23
     */
    @Override
    public ResponseWrapper addTenant(TenantParam tenantParam) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证状态参数
            StatusEnum statusEnum = StatusEnum.getEnumByCode(tenantParam.getStatus());
            if (statusEnum == null) {
                result.fail("传入的租户状态错误!");
                return result;
            }

            // 使用MapStruct转换参数为实体
            SysTenant sysTenant = TenantMapStructMapper.INSTANCE.tenantParamToSysTenant(tenantParam);

            // 设置额外字段
            sysTenant.setId(SystemNoUtils.generateSystemId());
            sysTenant.setCreateBy(SecurityUtils.getUserId());
            sysTenant.setCreateTime(LocalDateTime.now());

            // 插入数据库
            sysTenantMapper.insertSelective(sysTenant);
        } catch (Exception e) {
            log.error("新增租户时发生错误", e);
            result.fail("新增租户时发生错误: " + e.getMessage());
            throw e;
        }
        return result;
    }

    /**
     * 编辑租户
     *
     * @param tenantParam 租户参数
     * @return {@link ResponseWrapper}
     * @author zhou xun
     * @since 2025-11-23
     */
    @Override
    public ResponseWrapper editTenant(TenantParam tenantParam) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证租户是否存在
            SysTenant existingTenant = sysTenantMapper.selectByPrimaryKey(tenantParam.getId());
            if (existingTenant == null) {
                result.fail("传入的租户信息不存在!");
                return result;
            }

            // 验证状态参数
            StatusEnum statusEnum = StatusEnum.getEnumByCode(tenantParam.getStatus());
            if (statusEnum == null) {
                result.fail("传入的租户状态错误!");
                return result;
            }

            // 使用MapStruct转换参数为实体
            SysTenant sysTenant = TenantMapStructMapper.INSTANCE.tenantParamToSysTenant(tenantParam);

            // 设置更新信息
            sysTenant.setUpdateBy(SecurityUtils.getUserId());
            sysTenant.setUpdateTime(LocalDateTime.now());

            sysTenantMapper.updateByPrimaryKeySelective(sysTenant);
        } catch (Exception e) {
            log.error("编辑租户时发生错误", e);
            result.fail("编辑租户时发生错误: " + e.getMessage());
            throw e;
        }
        return result;
    }

    /**
     * 编辑租户状态
     *
     * @param id     租户id
     * @param status 租户状态 0 停用 1 启用
     * @return {@link ResponseWrapper}
     * @author zhou xun
     * @since 2025-11-23
     */
    @Override
    public ResponseWrapper editTenantStatus(String id, Integer status) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 业务验证 - 查询租户是否存在
            SysTenant sysTenant = sysTenantMapper.selectByPrimaryKey(id);
            if (Objects.isNull(sysTenant)) {
                result.fail("租户不存在!");
                return result;
            }

            // 验证状态参数
            StatusEnum statusEnum = StatusEnum.getEnumByCode(status);
            if (statusEnum == null) {
                result.fail("传入的租户状态错误!");
                return result;
            }

            // 更新租户状态
            SysTenant updateTenant = new SysTenant();
            updateTenant.setId(id);
            updateTenant.setStatus(status);
            updateTenant.setUpdateBy(SecurityUtils.getUserId());
            updateTenant.setUpdateTime(LocalDateTime.now());
            sysTenantMapper.updateByPrimaryKeySelective(updateTenant);
        } catch (Exception e) {
            log.error("编辑租户状态时发生错误", e);
            result.fail("编辑租户状态时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 删除租户
     *
     * @param tenantId 租户id
     * @return {@link ResponseWrapper}
     * @author zhou xun
     * @since 2025-11-23
     */
    @Override
    public ResponseWrapper deleteTenant(String tenantId) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 业务验证 - 查询租户是否存在
            SysTenant sysTenant = sysTenantMapper.selectByPrimaryKey(tenantId);
            if (Objects.isNull(sysTenant)) {
                result.fail("租户不存在!");
                return result;
            }

            // 检查是否为平台租户，平台租户不能删除
            if (SystemConstants.PLATFORM_TENANT_ID.equals(tenantId)) {
                result.fail("平台租户不能删除!");
                return result;
            }

            // 检查是否有子租户，如果有则不能删除
            List<SysTenant> children = sysTenantMapper.selectChildrenByParentId(tenantId);
            if (children != null && !children.isEmpty()) {
                result.fail("该租户下存在子租户，不能删除!");
                return result;
            }

            // 删除租户
            sysTenantMapper.deleteByPrimaryKey(tenantId);
        } catch (Exception e) {
            log.error("删除租户时发生错误", e);
            result.fail("删除租户时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 获取指定租户信息
     *
     * @param tenantId 租户ID
     * @return 租户信息包装对象
     */
    @Override
    public ObjectWrapper<SysTenant> selectTenantById(String tenantId) {
        ObjectWrapper<SysTenant> result = new ObjectWrapper<>();
        try {
            SysTenant tenant = sysTenantMapper.selectByPrimaryKey(tenantId);
            if (tenant != null) {
                result.setData(tenant);
            }
        } catch (Exception e) {
            log.error("查询租户信息时发生错误", e);
            result.fail("查询租户信息时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 根据父租户ID查询子租户列表
     *
     * @param parentId 父租户ID
     * @return 子租户列表包装对象
     */
    @Override
    public ListWrapper<SysTenant> selectChildrenByParentId(String parentId) {
        ListWrapper<SysTenant> result = new ListWrapper<>();
        try {
            List<SysTenant> children = sysTenantMapper.selectChildrenByParentId(parentId);
            if (null != children && !children.isEmpty()) {
                result.setData(children);
            }
        } catch (Exception e) {
            log.error("查询子租户列表时发生错误", e);
            result.fail("查询子租户列表时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 查询当前租户及其所有子租户
     *
     * @return 租户列表包装对象
     */
    @Override
    public ListWrapper<SysTenant> selectCurrentTenantTree() {
        ListWrapper<SysTenant> result = new ListWrapper<>();
        try {
            String currentTenantId = TenantContextHolder.getTenantId();
            List<SysTenant> tenantList;
            // 如果是平台租户，返回所有租户
            if (SystemConstants.PLATFORM_TENANT_ID.equals(currentTenantId)) {
                tenantList = sysTenantMapper.selectTenantList(null, null, null, null, null, null);
            } else {
                // 否则返回当前租户及其子租户
                tenantList = sysTenantMapper.selectTenantTree(currentTenantId);
            }
            result.setData(tenantList);
        } catch (Exception e) {
            log.error("查询当前租户树时发生错误", e);
            result.fail("查询当前租户树时发生错误: " + e.getMessage());
        }
        return result;
    }

    /**
     * 查询指定租户及其所有子租户
     *
     * @param tenantId 租户ID
     * @return 租户列表包装对象
     */
    @Override
    public ListWrapper<SysTenant> selectTenantTree(String tenantId) {
        ListWrapper<SysTenant> result = new ListWrapper<>();
        try {
            // 检查权限，只有平台租户或租户自己才能查询其租户树
            String currentTenantId = TenantContextHolder.getTenantId();
            if (!SystemConstants.PLATFORM_TENANT_ID.equals(currentTenantId) && !currentTenantId.equals(tenantId)) {
                result.fail("无权限查询该租户树");
                return result;
            }

            List<SysTenant> tenantList = sysTenantMapper.selectTenantTree(tenantId);
            result.setData(tenantList);
        } catch (Exception e) {
            log.error("查询租户树时发生错误", e);
            result.fail("查询租户树时发生错误: " + e.getMessage());
        }
        return result;
    }
}